package com.yunxi.core.web;

import com.yunxi.core.web.ResponseUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import com.yunxi.core.web.Model;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2010-10-21
 * Time: 10:14:40
 * To change this template use File | Settings | File Templates.
 */
public class TreeConfig implements java.io.Serializable {

    private String rootID;          //根ID
    private String rootText;        //根Text
    private Boolean state;           //打开关闭状 值为 open closed

    private String fieldID;             //ID字段
    private String fieldText;           //text字段
    private String fieldParentID;       //父ID字段
    private String fieldChild;          //是否有子节点的字值为 1有子节点没有子节
    private String[] fieldAttributes;      //附加属字段，分割
    private String fieldChecked;        //选中状字?值为 1选中0未中
    private String fieldOpen;
    private String fieldType;
    private Boolean isStorageTree;
    public TreeConfig() {

    }

    public TreeConfig(String rootID, String rootText, Boolean state,
                      String fieldID, String fieldText, String fieldParentID,
                      String fieldChild,String fieldType,Boolean isStorageTree) {
        this.setRootID(rootID);
        this.setRootText(rootText);
        this.setState(state);
        this.setFieldID(fieldID);
        this.setFieldText(fieldText);
        this.setFieldParentID(fieldParentID);
        this.setFieldChild(fieldChild);
        this.setFieldType(fieldType);
        this.setIsStorageTree(isStorageTree);
    }

    public TreeConfig(String rootID, String rootText, Boolean state,
                      String fieldID, String fieldText, String fieldParentID,
                      String fieldChild, String[] fieldAttributes, String fieldChecked) {
        this.setRootID(rootID);
        this.setRootText(rootText);
        this.setState(state);
        this.setFieldID(fieldID);
        this.setFieldText(fieldText);
        this.setFieldParentID(fieldParentID);
        this.setFieldChild(fieldChild);
        this.setFieldAttributes(fieldAttributes);
        this.setFieldChild(fieldChecked);
    }

    public TreeConfig(String rootID, String rootText, Boolean state,
                      String fieldID, String fieldText, String fieldParentID,
                      String fieldChild, String fieldAttributes, String fieldChecked) {
        this.setRootID(rootID);
        this.setRootText(rootText);
        this.setState(state);
        this.setFieldID(fieldID);
        this.setFieldText(fieldText);
        this.setFieldParentID(fieldParentID);
        this.setFieldChild(fieldChild);
        this.setFieldAttributes(fieldAttributes);
        this.setFieldChecked(fieldChecked);
    }

    public TreeConfig(String rootID, String rootText, Boolean state,
                      String fieldID, String fieldText, String fieldParentID) {
        this.setRootID(rootID);
        this.setRootText(rootText);
        this.setState(state);
        this.setFieldID(fieldID);
        this.setFieldText(fieldText);
        this.setFieldParentID(fieldParentID);
    }

    public TreeConfig(String rootID, String rootText, Boolean state,
                      String fieldID, String fieldText, String fieldParentID,
                      String fieldChild) {
        this.setRootID(rootID);
        this.setRootText(rootText);
        this.setState(state);
        this.setFieldID(fieldID);
        this.setFieldText(fieldText);
        this.setFieldParentID(fieldParentID);
        this.setFieldChild(fieldChild);
    }

    public TreeConfig(String rootID, String rootText, Boolean state,
                      String fieldID, String fieldText, String fieldParentID,
                      String fieldChild, String fieldAttributes) {
        this.setRootID(rootID);
        this.setRootText(rootText);
        this.setState(state);
        this.setFieldID(fieldID);
        this.setFieldText(fieldText);
        this.setFieldParentID(fieldParentID);
        this.setFieldChild(fieldChild);
        this.setFieldAttributes(fieldAttributes);
    }

    public TreeConfig(String rootID, String rootText, Boolean state,
                      String fieldID, String fieldText, String fieldParentID,
                      String fieldChild, String[] fieldAttributes) {
        this.setRootID(rootID);
        this.setRootText(rootText);
        this.setState(state);
        this.setFieldID(fieldID);
        this.setFieldText(fieldText);
        this.setFieldParentID(fieldParentID);
        this.setFieldChild(fieldChild);
        this.setFieldAttributes(fieldAttributes);
    }

    public Object toTreeData(List list, boolean showRoot) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        if (list != null && list.size() > 0) {
            List<Model> childTree = StringUtils.isEmpty(getFieldChild()) ?
                    createTreeData(list, getRootID(), 0) :
                    createTreeData(list, getRootID());
            return childTree != null && childTree.size() > 0 ? ResponseUtil.ok(childTree) : ResponseUtil.ok();
        } else {
            return ResponseUtil.ok("list date is null");
        }
    }

    private List<Model> createTreeData(List list, String parentID) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        List<Model> treeList = new ArrayList<Model>();
        //boolean find = false;
        for (Object obj : list) {
            boolean find = false;
            if(BeanUtils.getProperty(obj, getFieldParentID())!=null){
                if (BeanUtils.getProperty(obj, getFieldParentID()).equals(parentID)) {
                    find = true;
                    Model tree = new Model();
                    tree.set("id", BeanUtils.getProperty(obj, getFieldID()))
                            .set("value", BeanUtils.getProperty(obj, getFieldID()))
                            //.set("type", BeanUtils.getProperty(obj, getFieldType()))
                            .set("title", BeanUtils.getProperty(obj, getFieldText()))
                            .set("label", BeanUtils.getProperty(obj, getFieldText()))
                            .set("pid", BeanUtils.getProperty(obj, getFieldParentID()));
                    if (!StringUtils.isEmpty(getFieldChecked())) {
                        String ischecked = BeanUtils.getProperty(obj, getFieldChecked());
                        if (ischecked.equals("1")||ischecked.equals("true")) {
                            tree.set("checked", true);
                            //tree.set("selected", true);
                        }
                    }
                    if (getFieldAttributes() != null && getFieldAttributes().length > 0) {
                        Model attributeMap = new Model();
                        for (String attribute : getFieldAttributes()) {
                            attributeMap.put(attribute.trim(), BeanUtils.getProperty(obj, attribute.trim()));
                        }
                        tree.set("attributes", attributeMap);
                    }
                    if (BeanUtils.getProperty(obj, getFieldChild()).equals("1")) {
                        List<Model> childTree = createTreeData(list, (String) BeanUtils.getProperty(obj, getFieldID()));
                        if (childTree != null && childTree.size() > 0) {
                            tree.set("children", childTree);
                        }
                        if (getState()!=null) {
                            tree.set("expand", getState());
                            //tree.set("children", new ArrayList());
                        }
                    }else{
                        tree.set("expand", true);
                        //tree.set("children", new ArrayList());
                    }
                    treeList.add(tree);
                } else if (find) {
                    break;
                }
            }
        }
        return treeList;
    }

    private List<Model> createTreeData(List list, String parentID, int start) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        List<Model> treeList = new ArrayList<Model>();
        boolean find = false;
        for (int i = start; i < list.size(); i++) {
            Object obj = list.get(i);
            if (BeanUtils.getProperty(obj, getFieldParentID()).equals(parentID)
                    ||BeanUtils.getProperty(obj, getFieldParentID())==null) {
                find = true;
                Model tree = new Model();
                tree.set("id", BeanUtils.getProperty(obj, getFieldID()))
                        .set("value", BeanUtils.getProperty(obj, getFieldID()))
                        //.set("type", BeanUtils.getProperty(obj, getFieldType()))
                        .set("title", BeanUtils.getProperty(obj, getFieldText()))
                        .set("label", BeanUtils.getProperty(obj, getFieldText()))
                .set("pid", BeanUtils.getProperty(obj, getFieldParentID()));
                if (!StringUtils.isEmpty(getFieldChecked())) {
                    if (BeanUtils.getProperty(obj, getFieldChecked()).equals("1")) {
                        tree.set("expand", true);
                        //tree.set("children", new ArrayList());
                    }
                }
                if (getFieldAttributes() != null && getFieldAttributes().length > 0) {
                    Model attributeMap = new Model();
                    for (String attribute : getFieldAttributes()) {
                        attributeMap.put(attribute.trim(), BeanUtils.getProperty(obj, attribute.trim()));
                    }
                    tree.set("attributes", attributeMap);
                }
                if (i + 1 < list.size()) {
                    List<Model> childTree = createTreeData(list, (String) BeanUtils.getProperty(obj, getFieldID()), i + 1);
                    if (childTree != null && childTree.size() > 0) {
                        tree.set("children", childTree);
                    }else{
                        //tree.set("children", new ArrayList());
                    }
                    if (getState()!=null) {
                        tree.set("expand", getState());

                    }
                }
                treeList.add(tree);
            } else if (find) {
                break;
            }
        }
        return treeList;
    }

    public String getFieldID() {
        return fieldID;
    }

    public String getFieldParentID() {
        return fieldParentID;
    }

    public String getFieldText() {
        return fieldText;
    }

    public String getFieldChecked() {
        return fieldChecked;
    }

    public String[] getFieldAttributes() {
        return fieldAttributes;
    }

    public Boolean getState() {
        return state;
    }

    public String getRootID() {
        return rootID;
    }

    public String getRootText() {
        return rootText;
    }

    public String getFieldChild() {
        return fieldChild;
    }

    public void setFieldID(String fieldID) {
        this.fieldID = fieldID;
    }

    public void setFieldParentID(String fieldParentID) {
        this.fieldParentID = fieldParentID;
    }

    public void setFieldText(String fieldText) {
        this.fieldText = fieldText;
    }

    public void setFieldChecked(String fieldChecked) {
        this.fieldChecked = fieldChecked;
    }

    public void setFieldAttributes(String[] fieldAttributes) {
        this.fieldAttributes = fieldAttributes;
    }

    public void setFieldAttributes(String fieldAttributes) {
        if (!StringUtils.isEmpty(fieldAttributes))
            this.fieldAttributes = fieldAttributes.split(",");
    }

    public void setFieldChild(String fieldChild) {
        this.fieldChild = fieldChild;
    }

    public void setState(Boolean state) {
        this.state = state;
    }

    public void setRootID(String rootID) {
        this.rootID = rootID;
    }

    public void setRootText(String rootText) {
        this.rootText = rootText;
    }

    public String getFieldOpen()
    {
        return fieldOpen;
    }

    public void setFieldOpen(String fieldOpen)
    {
        this.fieldOpen = fieldOpen;
    }

    public String getFieldType()
    {
        return fieldType;
    }

    public void setFieldType(String fieldType)
    {
        this.fieldType = fieldType;
    }


    public Boolean getIsStorageTree() {
        return isStorageTree;
    }

    public void setIsStorageTree(Boolean isStorageTree) {
        this.isStorageTree = isStorageTree;
    }
}
